package com.cpp.server.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cpp.common.constant.redis.OperationConstant;
import com.cpp.common.enums.UserRoleEnum;
import com.cpp.pojo.dto.chapter.ChapterConfirmDTO;
import com.cpp.pojo.dto.chapter.ChapterCreateDTO;
import com.cpp.pojo.dto.chapter.ChapterQueryDTO;
import com.cpp.pojo.pojo.*;
import com.cpp.pojo.vo.chapter.ChapterConfirmVO;
import com.cpp.server.aspect.annotation.EndTimeRecord;
import com.cpp.server.aspect.annotation.StartTimeRecord;
import com.cpp.server.aspect.annotation.UserRole;
import com.cpp.server.client.PptGenerationClient;
import com.cpp.server.mapper.*;
import com.cpp.server.service.ChapterService;
import com.cpp.server.websocket.MyWebSocketHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;

@Service
@Slf4j
@RequiredArgsConstructor
public class ChapterServiceImpl extends ServiceImpl<ChapterMapper, Chapter> implements ChapterService {
    private final ChatClient generatepptTextChatClient;
    private final PptGenerationClient pptGenerationClient;
    private final ChapterMapper chapterMapper;
    private final CourseMapper courseMapper;
    private final KnowledgeMapper knowledgeMapper;
    private final QuestionMapper questionMapper;
    private final ResourceMapper resourceMapper;


    @Override
    @UserRole(roles = UserRoleEnum.TEACHER)
    @StartTimeRecord(value = OperationConstant.generateChapter)
    public ChapterConfirmVO generateResource(Long courseId) {

        //清理数据重新生成
        LambdaQueryWrapper<Chapter> chapterDelWrapper = new LambdaQueryWrapper<>();
        chapterDelWrapper.eq(Chapter::getCourseId, courseId);
        chapterMapper.delete(chapterDelWrapper);

        LambdaQueryWrapper<Knowledge> knowledgeDelWrapper = new LambdaQueryWrapper<>();
        knowledgeDelWrapper.eq(Knowledge::getCourseId, courseId);
        knowledgeMapper.delete(knowledgeDelWrapper);

        LambdaQueryWrapper<Question> questionDelWrapper = new LambdaQueryWrapper<>();
        questionDelWrapper.eq(Question::getCourseId, courseId);
        questionDelWrapper.eq(Question::getType, 0);//0是实训练习
        questionMapper.delete(questionDelWrapper);

        Course course = courseMapper.selectById(courseId);
        //调用ai生成知识点和实训
        String strChapter = generatepptTextChatClient.prompt()
                .user("只生成章节，以下是生成时需要用到的信息：" + course.getName() + course.getDescription() + "，courseId" + courseId + "，具体内容去向量库找")
                .call()
                .content();
        System.out.println(strChapter);


        //进行异步操作
        CompletableFuture.runAsync(() -> {
//        List<Chapter> chapters = generatePptTool.getChapters();
            LambdaQueryWrapper<Chapter> chapterQueryWrapper = new LambdaQueryWrapper<>();
            chapterQueryWrapper.eq(Chapter::getCourseId, courseId);
            List<Chapter> chapters = chapterMapper.selectList(chapterQueryWrapper);

            for (Chapter chapter : chapters) {

                String strKnowledge = generatepptTextChatClient.prompt()
                        .user("只生成知识点，以下是生成时需要用到的信息：" + course.getName() + course.getDescription() + "courseId" + courseId + "章节" + chapter + "对应的知识点，具体内容去向量库找")
                        .call()
                        .content();
                System.out.println(strKnowledge);

                LambdaQueryWrapper<Knowledge> knowledgeQueryWrapper = new LambdaQueryWrapper<>();
                knowledgeQueryWrapper.eq(Knowledge::getCourseId, courseId);
                List<Knowledge> knowledges = knowledgeMapper.selectList(knowledgeQueryWrapper);

                String strQuestion = generatepptTextChatClient.prompt()
                        .user("只生成实训练习，以下是生成时需要用到的信息：" + chapter.getTitle() + chapter.getContent() + "，courseId" + courseId + "知识点" + knowledges + "对应的实训练习具体内容去向量库找")
                        .call()
                        .content();
                System.out.println(strQuestion);

            }
            //查询生成的数据
            LambdaQueryWrapper<Chapter> chapterQueryWrapper2 = new LambdaQueryWrapper<>();
            chapterQueryWrapper2.eq(Chapter::getSort, 1);
            chapterQueryWrapper2.eq(Chapter::getCourseId, courseId);
            Chapter chapter = chapterMapper.selectOne(chapterQueryWrapper2);

            LambdaQueryWrapper<Knowledge> knowledgeQueryWrapper = new LambdaQueryWrapper<>();
            knowledgeQueryWrapper.eq(Knowledge::getChapterId, chapter.getId());
            List<Knowledge> knowledge = knowledgeMapper.selectList(knowledgeQueryWrapper);

            List<Long> knowledgeIds = knowledge.stream().map(Knowledge::getId).toList();
            LambdaQueryWrapper<Question> questionQueryWrapper = new LambdaQueryWrapper<>();
            questionQueryWrapper.in(Question::getKnowledgeIds, knowledgeIds);
            List<Question> question = questionMapper.selectList(questionQueryWrapper);

            //数据处理
            List<ChapterConfirmVO.KnowledgeVO> knowledgeVOS = new ArrayList<>();
            List<ChapterConfirmVO.QuestionVO> questionVOS = new ArrayList<>();
            //处理知识点
            for (Knowledge knowledge1 : knowledge) {
                ChapterConfirmVO.KnowledgeVO knowledgeVO = ChapterConfirmVO.KnowledgeVO
                        .builder()
                        .name(knowledge1.getName())
                        .content(knowledge1.getContent())
                        .knowledgeId(knowledge1.getId())
                        .build();
                knowledgeVOS.add(knowledgeVO);
            }
            //处理题目
            for (Question question1 : question) {
                ChapterConfirmVO.QuestionVO questionVO = ChapterConfirmVO.QuestionVO
                        .builder()
                        .questionId(question1.getId())
                        .content(question1.getContent())
                        .difficulty(question1.getDifficulty())
                        .answer(question1.getAnswer())
                        .analysis(question1.getAnalysis())
                        .build();
                questionVOS.add(questionVO);
            }
            //填充数据
            ChapterConfirmVO chapterConfirmVO = ChapterConfirmVO
                    .builder()
                    .chapterId(chapter.getId())
                    .sort(chapter.getSort())
                    .title(chapter.getTitle())
                    .content(chapter.getContent())
                    .duration(chapter.getDuration())
                    .knowledges(knowledgeVOS)
                    .questions(questionVOS)
                    .build();

            MyWebSocketHandler.sendMessageToUser(JSON.toJSONString(chapterConfirmVO));
        });


        //数据准备
//        LambdaQueryWrapper<Knowledge> knowledgeQueryWrapper = new LambdaQueryWrapper<>();
//        knowledgeQueryWrapper.eq(Knowledge::getCourseId, courseId);
//        List<Knowledge> knowledges = knowledgeMapper.selectList(knowledgeQueryWrapper);
//
//        LambdaQueryWrapper<Question>  questionQueryWrapper = new LambdaQueryWrapper<>();
//        questionQueryWrapper.eq(Question::getCourseId, courseId);
//        List<Question> questions = questionMapper.selectList(questionQueryWrapper);
//        List<Chapter> chapters = generatePptTool.getChapters();
//        List<Knowledge> knowledges = generatePptTool.getKnowledges();
//        List<Question> questions = generatePptTool.getQuestions();


        return null;
    }

    @Override
    @Transactional
    @UserRole(roles = UserRoleEnum.TEACHER)
    @EndTimeRecord(value = OperationConstant.generateChapter)
    public void confirm(ChapterConfirmDTO chapterConfirmDTO) {

        //封装数据
        Chapter chapter = Chapter.builder()
                .id(chapterConfirmDTO.getChapterId())
                .title(chapterConfirmDTO.getTitle())
                .content(chapterConfirmDTO.getContent())
                .duration(chapterConfirmDTO.getDuration())
                .build();

        //准备数据
        List<Question> questions = chapterConfirmDTO.getQuestions();
        List<Knowledge> knowledges = chapterConfirmDTO.getKnowledges();

        //给知识点上学科id
        Chapter chapterForCourseId = chapterMapper.selectById(chapterConfirmDTO.getChapterId());
        Course course = courseMapper.selectById(chapterForCourseId.getCourseId());
        for (Knowledge knowledge : knowledges) {
            knowledge.setSubjectId(course.getSubjectId());
        }

        //区分新增知识点和旧知识点（有无知识点id）stream流
        List<Knowledge> newKnowledges = knowledges.stream().filter(knowledge -> knowledge.getId() == null).toList();
        knowledges = knowledges.stream().filter(knowledge -> knowledge.getId() != null).toList();
        //实训练习
        List<Question> newQuestions = questions.stream().filter(question -> question.getId() == null).toList();
        questions = questions.stream().filter(question -> question.getId() != null).toList();


        //批量插入
        knowledgeMapper.insert(newKnowledges);
        questionMapper.insert(newQuestions);
        //批量更新
        questionMapper.updateById(questions);
        knowledgeMapper.updateById(knowledges);

        chapterMapper.updateById(chapter);
    }


    //查询某课程指定章节数据
    @Override
    @UserRole(roles = UserRoleEnum.TEACHER)
    @StartTimeRecord(value = OperationConstant.generateChapter)
    public ChapterConfirmVO getOneChapter(ChapterQueryDTO chapterQueryDTO) {

        //业务数据准备
        Long courseId = chapterQueryDTO.getCourseId();
        Integer sort = chapterQueryDTO.getSort();

        //查询章节信息
        LambdaQueryWrapper<Chapter> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Chapter::getCourseId, courseId);
        Long chapterCount = chapterMapper.selectCount(queryWrapper);
        queryWrapper.eq(Chapter::getSort, sort);
        Chapter chapter = chapterMapper.selectOne(queryWrapper);

        //查询章节知识点
        LambdaQueryWrapper<Knowledge> knowledgeQueryWrapper = new LambdaQueryWrapper<>();
        knowledgeQueryWrapper.eq(Knowledge::getChapterId, chapter.getId());
        List<Knowledge> knowledges = knowledgeMapper.selectList(knowledgeQueryWrapper);

        //查询实训练习
        List<Long> knIds = knowledges.stream().map(Knowledge::getId).toList();
        LambdaQueryWrapper<Question> questionQueryWrapper = new LambdaQueryWrapper<>();
        questionQueryWrapper.eq(Question::getType, 0);
        questionQueryWrapper.in(!knIds.isEmpty(), Question::getKnowledgeIds, knIds);
        List<Question> questions = questionMapper.selectList(questionQueryWrapper);

        //封装数据
        List<ChapterConfirmVO.KnowledgeVO> knowledgeVOS = knowledges.stream().map(knowledge ->
                ChapterConfirmVO.KnowledgeVO.builder()
                        .knowledgeId(knowledge.getId())
                        .name(knowledge.getName())
                        .content(knowledge.getContent())
                        .build()).toList();

        List<ChapterConfirmVO.QuestionVO> questionVOS = questions.stream().map(question ->
                ChapterConfirmVO.QuestionVO.builder()
                        .questionId(question.getId())
                        .content(question.getContent())
                        .answer(question.getAnswer())
                        .analysis(question.getAnalysis())
                        .difficulty(question.getDifficulty())
                        .build()).toList();

        //返回数据
        return ChapterConfirmVO.builder()
                .chapterId(chapter.getId())
                .content(chapter.getContent())
                .duration(chapter.getDuration())
                .sort(chapter.getSort())
                .title(chapter.getTitle())
                .knowledges(knowledgeVOS)
                .questions(questionVOS)
                .chapterCount(Math.toIntExact(chapterCount))
                .build();
    }

    @Override
    @UserRole(roles = UserRoleEnum.TEACHER)
    public void createChapter(ChapterCreateDTO chapterCreateDTO) {
        LambdaQueryWrapper<Chapter> chapterQueryWrapper = new LambdaQueryWrapper<>();
        chapterQueryWrapper.eq(Chapter::getCourseId, chapterCreateDTO.getCourseId());
        Long sort = chapterMapper.selectCount(chapterQueryWrapper);


        Chapter chapter = Chapter.builder()
                .courseId(chapterCreateDTO.getCourseId())
                .title(chapterCreateDTO.getTitle())
                .content(chapterCreateDTO.getContent())
                .duration(chapterCreateDTO.getDuration())
                .sort((int) (sort + 1))
                .build();
        chapterMapper.insert(chapter);

        if (chapterCreateDTO.getIsGenerate() == 1) {
            //准备生成数据
            Long courseId = chapterCreateDTO.getCourseId();
            Course course = courseMapper.selectById(courseId);

            String strKnowledge = generatepptTextChatClient.prompt()
                    .user("只生成知识点，以下是生成时需要用到的信息：" + course.getName() + course.getDescription() + "courseId" + courseId + "章节" + chapter + "对应的知识点，具体内容去向量库找")
                    .call()
                    .content();
            System.out.println(strKnowledge);

            LambdaQueryWrapper<Knowledge> knowledgeQueryWrapper = new LambdaQueryWrapper<>();
            knowledgeQueryWrapper.eq(Knowledge::getCourseId, courseId);
            knowledgeQueryWrapper.eq(Knowledge::getChapterId, chapter.getId());
            List<Knowledge> knowledges = knowledgeMapper.selectList(knowledgeQueryWrapper);

            String strQuestion = generatepptTextChatClient.prompt()
                    .user("只生成实训练习，以下是生成时需要用到的信息：" + chapter.getTitle() + chapter.getContent() + "，courseId" + courseId + "知识点" + knowledges + "对应的实训练习具体内容去向量库找")
                    .call()
                    .content();
            System.out.println(strQuestion);
        }
    }
}
